///////////////////////////////////////////////////////////////////////////////////////////////////
/// \file configuration.h
///
/// \brief   header file for the Configuration class
///
///////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef EDS_CONFIGURATION_HEADER
#define EDS_CONFIGURATION_HEADER

#include<vector>
#include<cassert>

namespace eds {

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  /// \brief  a class to hold a lattice configuration
  ///
  ///////////////////////////////////////////////////////////////////////////////////////////////////
  class Configuration {

    private:

      /// \brief  the number of sites
      int _ns;

      /// \brief  the total occupation of the lattice
      int _to;

      /// \brief  the number of configurations on each site
      int _cps;

      /// \brief  flag to tell whether or not all configuration have been looped over
      bool _finished;

      /// \brief  the occupation number vector
      std::vector<int> _occ_vec;

      /// \brief  the number of times each occupation occurs
      std::vector<int> _occurances;

    public:

      int & operator[](const int i) { assert( i >= 0 && i < _occ_vec.size() ); return _occ_vec[i]; }
      int operator[](const int i) const { assert( i >= 0 && i < _occ_vec.size() ); return _occ_vec[i]; }

      const int * c_ptr() const { assert( _occ_vec.size() > 0 ); return &_occ_vec[0]; }
      int * c_ptr() { assert( _occ_vec.size() > 0 ); return &_occ_vec[0]; }

      Configuration(const int ns, const int to, const int cps);

      void reset();
      void operator++();
      void operator++(int) { ++(*this); }
      bool finished() const { return _finished; }

      Configuration & operator=(const Configuration & other);

  };

}

#endif
